/* * Copyright 2014 lb * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.github.lburgazzoli.quickfixj.transport.netty; import com.github.lburgazzoli.quickfixj.transport.AbstractTransport; import com.github.lburgazzoli.quickfixj.transport.FIXSessionHelper; import com.github.lburgazzoli.quickfixj.transport.FIXSessionType; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.PooledByteBufAllocator; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelOption; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import quickfix.SessionID; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; /** * */ public class NettySocketInitiator extends AbstractTransport implements INettyStateHandler { private static Logger LOGGER = LoggerFactory.getLogger(NettySocketInitiator.class); private Bootstrap m_boot; /** * c-tor * * @param session */ public NettySocketInitiator(FIXSessionHelper session) { super(session); m_boot = null; } // ************************************************************************* // // ************************************************************************* /** * */ @Override public void connect() { try { m_boot = new Bootstrap(); m_boot.group(new NioEventLoopGroup()); m_boot.channel(NioSocketChannel.class); m_boot.option(ChannelOption.SO_KEEPALIVE, true); m_boot.option(ChannelOption.TCP_NODELAY, true); m_boot.option(ChannelOption.ALLOCATOR,new PooledByteBufAllocator(true)); m_boot.handler(new NettyChannelInitializer(this,getHelper(), FIXSessionType.INITIATOR)); SessionID sid = getHelper().getSession().getSessionID(); String host = getHelper().getSettings().getString("SocketConnectHost"); int port = getHelper().getSettings().getInt("SocketConnectPort"); m_boot.remoteAddress(new InetSocketAddress(host,port)); if(!isRunning()) { setRunning(true); doConnect(); } } catch(Exception e) { LOGGER.warn("Exception", e); setRunning(false); } } @Override public void disconnect() { super.disconnect(); if(m_boot != null) { m_boot.group().shutdownGracefully(); } } // ************************************************************************* // // ************************************************************************* /** * */ private void doConnect() { ChannelFuture future = m_boot.connect(); future.addListener(new ChannelFutureListener() { public void operationComplete(ChannelFuture future) { if(future.isDone() && future.isSuccess()) { setChannel(new NettyChannel(future.channel())); } else if(!future.isSuccess() && !future.isCancelled()) { LOGGER.warn("Error", future.cause()); doReconnect(); } } }); } private void doReconnect() { if(isRunning() && m_boot != null) { Runnable task = new Runnable() { public void run() { doConnect(); } }; m_boot.group().schedule(task,5,TimeUnit.SECONDS); } } // ************************************************************************* // // ************************************************************************* @Override public void onConnect(Channel channel) { } @Override public void onDisconnect(Channel channel) { doReconnect(); } }